home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 2.toast / pc / sample code / overview / dave falkenburg's sprocket / docwindow.cp < prev    next >
Encoding:
Text File  |  2000-09-28  |  9.8 KB  |  396 lines

  1. /*
  2.     File:        DocWindow.cp
  3.  
  4.     Contains:    A simple document window
  5.  
  6.     Written by: Dave Falkenburg    
  7.  
  8.     Copyright:    Copyright © 1993-1999 by Apple Computer, Inc., All Rights Reserved.
  9.  
  10.                 You may incorporate this Apple sample source code into your program(s) without
  11.                 restriction. This Apple sample source code has been provided "AS IS" and the
  12.                 responsibility for its operation is yours. You are not permitted to redistribute
  13.                 this Apple sample source code as "Apple sample source code" after having made
  14.                 changes. If you're going to re-distribute the source, we require that you make
  15.                 it clear in the source that the code was descended from Apple sample source
  16.                 code, but that you've made changes.
  17.  
  18.     Change History (most recent first):
  19.                 8/19/1999    Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
  20.                 9/27/94        DRF                Changes for Dave Mark: AppLib.h is now Sprocket.h.
  21.                 9/9/94        DRF                Reordered headers and removed redundant #includes.
  22.                 9/4/94        DRF                Added scroll bars and revised dragging methods.
  23.  
  24. */
  25.  
  26. #include "Sprocket.h"
  27. #include "DocWindow.h"
  28.  
  29. #include <LowMem.h>        //    for LMGetCurApName()
  30. #include <ToolUtils.h>    //    for NumToString()
  31. #include <Icons.h>        //    for PlotIconID
  32. #include <TextUtils.h>
  33.  
  34.  
  35. unsigned long        TDocWindow::fgUntitledTagCount = 0;
  36.  
  37. const short            kHeaderHeight = 20;
  38.  
  39. const short            kFirstSpinningArrowIconID = 801;
  40. const short            kLastSpinningArrowIconID = 808;
  41.  
  42. const short            kDocWindowTemplateID = 1026;
  43.  
  44.  
  45.  
  46. static pascal void    DocWindowControlActionProc(ControlHandle theControl,short partCode);
  47. static void            SpinDocWindowArrows(TDocWindow * windowToSpin);
  48.  
  49.  
  50. //    Functions which are called from external scope, but in turn invoke
  51. //    DocWindow methods. These really could be moved to "Window.h"
  52.  
  53. static ControlActionUPP
  54. DocWindowControlAction = NewControlActionProc(DocWindowControlActionProc);
  55.  
  56. static pascal void
  57. DocWindowControlActionProc(ControlHandle theControl,short partCode)
  58.     {
  59.     TDocWindow * aDocWindow = NULL;
  60.     
  61.     aDocWindow = (TDocWindow *) GetControlReference(theControl);
  62.  
  63.     if (aDocWindow)
  64.         aDocWindow->DoControlAction(theControl,partCode);
  65.     }
  66.  
  67.  
  68. static void
  69. SpinDocWindowArrows(TDocWindow * windowToSpin)
  70.     {
  71.     while (1)
  72.         {
  73.         windowToSpin->SpinHeaderArrows();
  74.         YieldToAnyThread();
  75.         }
  76.     }
  77.  
  78.  
  79.  
  80. //    methods
  81.  
  82. TDocWindow::TDocWindow()
  83.     {
  84.     OSErr    err;
  85.  
  86.     fCurrentSpinningArrowIconID = kFirstSpinningArrowIconID;
  87.     fVerticalScrollActive = fHorizontalScrollActive = false;
  88.  
  89.     fCanAcceptDrag = false;
  90.     fDragTargetRgn = NULL;
  91.  
  92.     TDocWindow::fgUntitledTagCount++;            //    Starts out as zero but we want “Untitled-1”
  93.     this->CreateWindow();
  94.     
  95.     if (gHasThreadManager)
  96.         {
  97.         err = NewThread(kCooperativeThread,(ThreadEntryProcPtr) SpinDocWindowArrows,this,0,0,nil,&fSpinnerThreadID);
  98.         if (err != noErr)
  99.             DebugStr((StringPtr) "\pNewThread failed");
  100.         }
  101.     }
  102.  
  103. TDocWindow::~TDocWindow()
  104.     {
  105.     OSErr    err;
  106.  
  107.     //    NEWS OF THE WEIRD!
  108.     //    If you pass true for recyleThread param, the heap block for the stack isn’t
  109.     //    disposed— it gets placed in the default cooperative thread pool of “premade”
  110.     //    threads.
  111.     //
  112.     //    To optimize memory usage, I might just want to go ahead and create
  113.     //    a thread pool at application startup so we can avoid moving memory around
  114.     //    so much.
  115.     
  116.     if (gHasThreadManager)
  117.         {
  118.         err = DisposeThread(fSpinnerThreadID,nil,false);
  119.         if (err != noErr)
  120.             DebugStr((StringPtr) "\pDisposeThread failed");
  121.         }
  122.     }
  123.  
  124.     
  125. WindowPtr
  126. TDocWindow::MakeNewWindow(WindowPtr behindWindow)
  127.     {
  128.     WindowPtr    aWindow = GetNewColorOrBlackAndWhiteWindow(kDocWindowTemplateID,nil,behindWindow);
  129.     Str255        titleString;
  130.     GrafPtr        savedPort;
  131.     Rect        scrollRect;
  132.     
  133.     GetPort(&savedPort);
  134.     if (aWindow)
  135.         {
  136.         //    make the window exciting & different
  137.         
  138.         //    Can’t call nudge because it assumes the window is visible!
  139.         
  140.         //    Nudge(fgUntitledTagCount * kHeaderHeight,fgUntitledTagCount * kHeaderHeight);
  141.     
  142.         GetWTitle(aWindow,titleString);
  143.         if (StrLength(titleString) != 0)
  144.             {
  145.             Str255 numberString;
  146.             
  147.             NumToString(fgUntitledTagCount,numberString);
  148.             BlockMove(&numberString[1],&titleString[titleString[0]+1],numberString[0]);
  149.             titleString[0] += numberString[0];
  150.             }
  151.         SetWTitle(aWindow,titleString);
  152.  
  153.         SetPort(aWindow);
  154.  
  155.         //    create vertical scroll bar
  156.         scrollRect.top = aWindow->portRect.top + kHeaderHeight -1;
  157.         scrollRect.left = aWindow->portRect.right - kScrollbarWidth + 1;
  158.         scrollRect.bottom = aWindow->portRect.bottom - kScrollbarWidth + kScrollbarTweak;
  159.         scrollRect.right = aWindow->portRect.right + 1;
  160.  
  161.         fVerticalScroll = NewControl(aWindow,&scrollRect,"\p", true,/* value = */ 0 ,/* min = */ 0, /* max = */ 255, scrollBarProc, (long) this);
  162.         SetControlAction(fVerticalScroll,DocWindowControlAction);
  163.  
  164.         //    create horizontal scroll bar
  165.         scrollRect.top = aWindow->portRect.bottom - kScrollbarWidth + 1;
  166.         scrollRect.left = aWindow->portRect.left -1;
  167.         scrollRect.bottom = aWindow->portRect.bottom + 1;
  168.         scrollRect.right = aWindow->portRect.right - kScrollbarWidth + kScrollbarTweak;
  169.         fHorizontalScroll = NewControl(aWindow,&scrollRect,"\p", true,/* value = */ 0 ,/* min = */ 0, /* max = */ 255, scrollBarProc, (long) this);
  170.         SetControlAction(fHorizontalScroll,DocWindowControlAction);
  171.  
  172.         ShowWindow(aWindow);
  173.         }
  174.     SetPort(savedPort);
  175.  
  176.     return aWindow;
  177.     }
  178.  
  179.  
  180. void
  181. TDocWindow::Activate(Boolean activating)
  182.     {
  183.     short    verticalHiliteValue,horizontalHiliteValue;
  184.     
  185.     if (activating)
  186.         {
  187.         verticalHiliteValue = (fVerticalScrollActive ? 0 : 255);
  188.         horizontalHiliteValue = (fHorizontalScrollActive ? 0 : 255);
  189.         }
  190.     else
  191.         {
  192.         verticalHiliteValue = horizontalHiliteValue = 254;
  193.          }
  194.  
  195.     HiliteControl(fVerticalScroll,verticalHiliteValue);
  196.     HiliteControl(fHorizontalScroll,horizontalHiliteValue);
  197.  
  198.     DrawJustTheGrowIcon(fWindow);
  199.     }
  200.  
  201.  
  202. void
  203. TDocWindow::AdjustCursor(EventRecord * /* anEvent */)
  204.     {
  205.     }
  206.  
  207.  
  208. void
  209. TDocWindow::Draw(void)
  210.     {
  211.     EraseRect(&fWindow->portRect);
  212.  
  213.     MoveTo(0,kHeaderHeight-3); LineTo(fWindow->portRect.right,kHeaderHeight-3);
  214.     MoveTo(0,kHeaderHeight-1); LineTo(fWindow->portRect.right,kHeaderHeight-1);
  215.  
  216.     UpdateControls(fWindow,fWindow->visRgn);
  217.  
  218.     DrawJustTheGrowIcon(fWindow);
  219.     }
  220.  
  221.     
  222. void
  223. TDocWindow::Click(EventRecord * anEvent)
  224.     {
  225.     ControlHandle    theControl = NULL;
  226.     short            theControlPartCode;
  227.     
  228.     theControlPartCode = FindControl(anEvent->where,fWindow,&theControl);
  229.     
  230.     if (theControl != NULL)
  231.         {
  232.         //    NOTE: NON-NULL action procs don’t work for scrollbar thumbs!
  233.         if (theControlPartCode != kControlIndicatorPart)
  234.             (void) TrackControl(theControl,anEvent->where,DocWindowControlAction);
  235.         else
  236.             {
  237.             //    You might ask: What the heck is CW doing to make this work???
  238.             //    They don’t call TrackControl, instead they roll their own
  239.             //    using TestControl & SetControlValue. This is left as an
  240.             //    excercise to the reader, and we do the OLD HI method of
  241.             //    dragging a ghost thumb around
  242.  
  243.             (void) TrackControl(theControl,anEvent->where,NULL);
  244.             }
  245.         }
  246.     else
  247.         {
  248.         if (MyFrontNonFloatingWindow() != fWindow)
  249.             {
  250.             this->Select();
  251.             }
  252.         else
  253.             {
  254.             }
  255.         }
  256.     }
  257.  
  258.  
  259. void
  260. TDocWindow::AdjustForNewWindowSize(Rect *oldSize,Rect * newSize)
  261.     {
  262.     Rect    growBoxRect;
  263.     
  264.     //    Invalidate the old grow box
  265.     growBoxRect.top = oldSize->bottom - kScrollbarWidth;
  266.     growBoxRect.bottom = oldSize->bottom;
  267.     growBoxRect.left = oldSize->right - kScrollbarWidth;
  268.     growBoxRect.right = oldSize->right;
  269.     InvalRect(&growBoxRect);
  270.     
  271.     //    HideControl does an InvalRect for us, and hides all the jerky control movement from the user.
  272.     HideControl(fVerticalScroll);
  273.     HideControl(fHorizontalScroll);
  274.  
  275.     MoveControl(fVerticalScroll,newSize->right - kScrollbarWidth + 1,newSize->top + kHeaderHeight-1);
  276.     MoveControl(fHorizontalScroll,newSize->left - 1,newSize->bottom - kScrollbarWidth + 1);
  277.  
  278.     SizeControl(fVerticalScroll,kScrollbarWidth,(newSize->bottom - newSize->top) - kHeaderHeight + 1 - kScrollbarWidth + kScrollbarTweak);
  279.     SizeControl(fHorizontalScroll,(newSize->right - newSize->left + 1) - kScrollbarWidth + kScrollbarTweak,kScrollbarWidth);
  280.  
  281.     //    Now that we’ve moved & resized the scroll bars, show them.
  282.     ShowControl(fVerticalScroll);
  283.     ShowControl(fHorizontalScroll);
  284.  
  285.     DrawJustTheGrowIcon(fWindow);
  286.     }
  287.  
  288.  
  289. Boolean
  290. TDocWindow::Close(void)
  291.     {
  292.     StandardCloseResult    result;
  293.     Str255                title;
  294.     
  295.     GetWTitle(this->fWindow,title);
  296.     result = StandardCloseDocument(LMGetCurApName(),title,false,false);
  297.  
  298.     if (result != kCancelSaveDocument)
  299.         {
  300.         return TWindow::Close();
  301.         }
  302.     return false;
  303.     }
  304.  
  305.  
  306. OSErr
  307. TDocWindow::DragEnterWindow(DragReference theDrag)
  308.     {
  309.     //    preflight to determine if we can accept any of the drag
  310.     
  311.     fCanAcceptDrag = true;        //    accept anything for now
  312.  
  313.     fDragTargetRgn = NewRgn();
  314.     SetRectRgn( fDragTargetRgn,
  315.                 fWindow->portRect.left,
  316.                 fWindow->portRect.top + kHeaderHeight,
  317.                 fWindow->portRect.right-kScrollbarWidth+1,
  318.                 fWindow->portRect.bottom-kScrollbarWidth+1);
  319.     
  320.     return this->DragInWindow(theDrag);
  321.     }
  322.  
  323.  
  324. OSErr
  325. TDocWindow::DragInWindow(DragReference theDrag)
  326.     {
  327.     if (fCanAcceptDrag)
  328.         {
  329.         Point    mouseLoc, pinnedMouseLoc;
  330.  
  331.         (void) GetDragMouse(theDrag,&mouseLoc,&pinnedMouseLoc);
  332.         GlobalToLocal(&mouseLoc);
  333.         
  334.         if (PtInRgn(mouseLoc,fDragTargetRgn))
  335.             ShowDragHilite(theDrag,fDragTargetRgn,true);
  336.         else
  337.             HideDragHilite(theDrag);
  338.         }
  339.         
  340.     return noErr;
  341.     }
  342.  
  343.  
  344. OSErr
  345. TDocWindow::DragLeaveWindow(DragReference theDrag)
  346.     {
  347.     fCanAcceptDrag = false;
  348.     DisposeRgn(fDragTargetRgn);    
  349.     HideDragHilite(theDrag);
  350.     return noErr;
  351.     }
  352.  
  353.  
  354. OSErr
  355. TDocWindow::HandleDrop(DragReference /* theDrag */)
  356.     {
  357.     return noErr;
  358.     }
  359.  
  360.  
  361. void
  362. TDocWindow::DoControlAction(ControlHandle whichControl,short /* whichPart */)
  363.     {
  364.     if (whichControl == fVerticalScroll)
  365.         {
  366.         }
  367.     else if (whichControl == fHorizontalScroll)
  368.         {
  369.         }
  370.     }
  371.  
  372.  
  373. void
  374. TDocWindow::SpinHeaderArrows()
  375.     {
  376.     GrafPtr    oldPort;
  377.     
  378.     GetPort(&oldPort);
  379.     SetPort(fWindow);
  380.     
  381.     Rect    r;
  382.     
  383.     fCurrentSpinningArrowIconID++;
  384.     
  385.     if (fCurrentSpinningArrowIconID > kLastSpinningArrowIconID)
  386.         fCurrentSpinningArrowIconID = kFirstSpinningArrowIconID;
  387.     
  388.     r.top = fWindow->portRect.top;
  389.     r.left = fWindow->portRect.left+4;
  390.     r.bottom = r.top + 16;
  391.     r.right = r.left + 16;
  392.     (void) PlotIconID(&r,atNone,ttNone,fCurrentSpinningArrowIconID);
  393.  
  394.     SetPort(oldPort);
  395.     }
  396.